<template>
  <div ref="echartsRef" :style="{ width: '100%', height: '100%' }"></div>
</template>

<script lang="ts" setup>
import { ref, watch, onMounted, onBeforeUnmount } from 'vue';
import * as echarts from 'echarts';

const props = defineProps({
  echartsData: {
    type: Object,
    default: () => ({})
  },
  deviceInfo: {
    type: Object,
    default: () => ({})
  }
});

const echartsRef = ref(null);
const myChart = ref(null);
const isBar = ref(false);

// Color constants
const COLORS = ['#5470C6', '#91CC75'];

// Helper functions
const getValveLabel = (value): string => (value === 1 ? '关闭' : '开启');

const getThresholdLabel = (data, type) => {
  if (type === 'line' || type === 'wrjLine') {
    const color = data.borderColor || data.color;
    return color === '#FF7804' ? '低报阈值' : '高报阈值';
  } else if (type === 'wptLine') {
    if (data.value === '1500' || data.value === '0.18') return '低限压力';
    if (data.value === '3800' || data.value === '0.385') return '高限压力';
  }
  return '';
};

const adjustWptLineValues = (data, yaxisList) => {
  if (yaxisList[0]?.unit === 'Mpa') {
    return data.map((item) => ({
      ...item,
      yAxis: String(Number(item.yAxis) / 1000000)
    }));
  }
  return data.map((item) => {
    if (item.yAxis === '0.18' || item.yAxis === '1540') {
      return {
        ...item,
        lineStyle: { color: 'red' },
        label: { color: 'red' }
      };
    }
    return item;
  });
};

const uniqueArray = (arr) => arr.filter((item, index) => arr.indexOf(item) === index);

const processValveLineChart = (option) => {
  const xDataLabel = {};
  const xDataStr = option.xAxis[0].data;
  const xDataDay = uniqueArray(xDataStr.map((item) => item.substr(0, 5)));

  let xData = [];
  let indexDayCur = 0;

  xDataDay.forEach((itemDay) => {
    xDataStr.forEach((item) => {
      if (item.substr(0, 5) === itemDay) {
        xData.push(indexDayCur * 1440 + 60 * item.substr(6, 2) + 1 * item.substr(9, 2));
      }
    });
    indexDayCur++;
  });

  // Adjust intervals
  xData.forEach((item, index) => {
    if (index > 0) {
      const intervalValue = item - xData[index - 1];
      if (intervalValue < 60) {
        xData[index] = xData[index - 1] + 60;
        for (let i = index + 1; i < xData.length; i++) {
          xData[i] += 60 - intervalValue;
        }
      }
    }
  });

  // Shift left
  const firstValue = xData[0];
  xData = xData.map((item) => item - firstValue + 60);

  // Prepare mark line data
  const intervalValue = Math.floor(xData.length / 6) + 1;
  const xDataMarkLine = xData.filter((_, index) => index % intervalValue === 0);

  // Prepare series data
  const yData = option.series[0].data;
  const seriesData = xData.map((item, index) => {
    xDataLabel[item] = xDataStr[index];
    return [item, yData[index]];
  });

  // Update option
  option.xAxis[0] = {
    ...option.xAxis[0],
    type: 'value',
    axisTick: { show: false },
    splitLine: { show: false },
    axisLabel: { show: false }
  };

  option.series[0].data = seriesData;
  option.series[0].markLine = {
    symbol: false,
    silent: true,
    label: {
      position: 'start',
      formatter: (obj) => xDataLabel[obj.value]
    },
    lineStyle: { color: '#fff', width: 0 },
    data: xDataMarkLine.map((val) => ({ xAxis: val }))
  };

  option.tooltip.formatter = (params) => {
    let res = xDataLabel[params[0].data[0]] + '<br/>';
    params.forEach((param) => {
      res += `${param.seriesName} : ${getValveLabel(param.data[1])}<br/>`;
    });
    return res;
  };

  return option;
};

const getYAxisConfig = (item, chartsType) => {
  const config: any = {
    type: item.value,
    name: item.name,
    position: item.position,
    axisLine: {
      show: chartsType !== 'valveLine',
      max: '100',
      lineStyle: {
        color: '#FFFFFF',
        opacity: 0.8
      }
    },
    axisTick: {
      show: false,
      lineStyle: {
        color: 'red',
        width: 2
      }
    },
    axisLabel: {
      formatter: `{value}${item.unit}`,
      interval: 3
    },
    splitLine: {
      show: false
    }
  };

  switch (chartsType) {
    case 'valveLine':
      config.min = 0;
      config.max = 2;
      config.axisLabel = {
        // 使用类型断言以满足 ECharts 配置要求，实际运行时支持函数形式
        formatter: ((value: number): string => getValveLabel(value)) as any
      };
      break;
    case 'line':
      if (props.deviceInfo?.equipmentClassify === '14') {
        config.max = 400;
      } else if (props.deviceInfo?.equipmentClassify === '2') {
        // 其他单位不设置 max，让 ECharts 自动计算最大值
        item.unit = 'ppm';
      } else {
        config.max = 100;
      }
      config.splitNumber = 2;
      break;
    case 'wptLine':
      config.min = item.unit === 'Pa' ? 0 : 0;
      config.max = item.unit === 'Pa' ? 6000 : 0.4;
      config.splitNumber = 2;
      break;
    case 'barAndline':
      config.min = 0;
      config.max = 100;
      config.splitNumber = 2;
      break;
  }

  return config;
};

const getSeriesConfig = (item, index, chartsType) => {
  const commonLineStyle = {
    shadowColor: 'rgba(0, 0, 0, .3)',
    shadowBlur: 0,
    shadowOffsetY: 5,
    shadowOffsetX: 5
  };

  const commonItemStyle = {
    borderColor: '#fff',
    borderWidth: 1,
    shadowColor: 'rgba(0, 0, 0, .3)',
    shadowBlur: 0,
    shadowOffsetY: 2,
    shadowOffsetX: 2
  };

  if (item.type === 'line') {
    const isFirstLine = index === 0;
    const lineColor = isFirstLine ? '#FFCC5A' : '#FF865A';

    const config = {
      ...item,
      showAllSymbol: true,
      showSymbol: chartsType === 'valveLine',
      symbol: chartsType === 'valveLine' ? 'circle' : 'none',
      step: chartsType === 'valveLine' ? 'end' : undefined,
      lineStyle: {
        ...commonLineStyle,
        ...commonLineStyle,
        color: lineColor
      },
      label: {
        show: true,
        position: 'top',
        textStyle: {
          color: lineColor
        },
        ...(chartsType === 'valveLine'
          ? {
              show: false,
              formatter: (params) => getValveLabel(params.data)
            }
          : {})
      },
      itemStyle: {
        ...commonItemStyle,
        color: lineColor
      }
    };

    if (isFirstLine) {
      config.areaStyle = {
        color: new echarts.graphic.LinearGradient(
          0,
          0,
          0,
          1,
          [
            { offset: 0, color: 'rgba(108,80,243,0.3)' },
            { offset: 1, color: 'rgba(108,80,243,0)' }
          ],
          false
        ),
        shadowColor: 'rgba(108,80,243, 0.9)',
        shadowBlur: 12
      };
    } else {
      config.areaStyle = {
        color: new echarts.graphic.LinearGradient(
          0,
          0,
          0,
          1,
          [
            { offset: 0, color: 'rgba(0,202,149,0.3)' },
            { offset: 1, color: 'rgba(0,202,149,0)' }
          ],
          false
        ),
        shadowColor: 'rgba(0,202,149, 0.9)',
        shadowBlur: 12
      };
    }

    if (item.markLine) {
      config.markLine = {
        label: {
          show: true,
          position: 'end',
          formatter: (params) => `${getThresholdLabel(params, chartsType)}: ${params.value}`
        },
        lineStyle: {
          type: isFirstLine ? 'dashed' : 'solid',
          color: '#FF1D00',
          width: 1
        },
        data: chartsType === 'wptLine' ? adjustWptLineValues(item.markLine.data, props.echartsData.yaxisList) : item.markLine.data,
        precision: 2 // 设置精度
      };
    }

    return config;
  } else if (item.type === 'bar') {
    isBar.value = true;
    const gradientColors = index === 3 ? ['#57FF6A', '#2b6098'] : ['#27E6FF', '#2b6098'];

    return {
      ...item,
      barWidth: 20,
      itemStyle: {
        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          { offset: 0, color: gradientColors[0] },
          { offset: 1, color: gradientColors[1] }
        ]),
        barBorderRadius: index === 3 ? 11 : 12
      }
    };
  }

  return item;
};

const drawLine = (echartsData) => {
  if (!echartsRef.value || !echartsData) return;

  // Initialize or reuse chart instance
  if (!myChart.value) {
    myChart.value = markRaw(echarts.init(echartsRef.value));
  }

  const chartsType = echartsData.context?.chartsType;
  isBar.value = false;

  // Prepare yAxis configuration
  const yAxis = echartsData.yaxisList?.map((item) => getYAxisConfig(item, chartsType)) || [];

  // Prepare xAxis configuration
  const xAxis =
    echartsData.xaxisList?.map((item) => ({
      ...item,
      type: 'category',
      axisLine: {
        show: true,
        lineStyle: {
          color: COLORS[echartsData.xaxisList.indexOf(item)]
        }
      },
      axisLabel: {
        show: true,
        color: '#fff'
      },
      splitLine: {
        show: false,
        lineStyle: {
          color: ['#2F8CFF'],
          width: 1,
          type: 'solid'
        }
      }
    })) || [];

  // Prepare series configuration
  const series = echartsData.seriesList?.map((item, index) => getSeriesConfig(item, index, chartsType)) || [];

  // Base option
  const option = {
    color: COLORS,
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'cross',
        label: {
          backgroundColor: '#6a7985'
        }
      }
    },
    grid: {
      top: '20%',
      right: '15%',
      bottom: '20%',
      left: '14%'
    },
    legend: {
      data: echartsData.legend?.data || [],
      top: '4%',
      textStyle: {
        fontSize: 14,
        color: '#ffffff'
      }
    },
    dataZoom: isBar.value
      ? [
          {
            type: 'inside',
            start: 0,
            end: 100
          },
          {
            start: 0,
            end: 100
          }
        ]
      : [],
    xAxis,
    yAxis,
    series
  };
  console.log(option);
  // Special handling for valve line chart
  if (chartsType === 'valveLine') {
    processValveLineChart(option);
  }

  myChart.value.setOption(option, true);
};

// Watch for echartsData changes
watch(
  () => props.echartsData,
  (newVal) => {
    drawLine(newVal);
  },
  { deep: true }
);

// Initialize on mount
onMounted(() => {
  drawLine(props.echartsData);

  const handleResize = () => {
    if (myChart.value) {
      myChart.value.resize();
    }
  };

  window.addEventListener('resize', handleResize);

  onBeforeUnmount(() => {
    window.removeEventListener('resize', handleResize);
    if (myChart.value) {
      myChart.value.dispose();
    }
  });
});
</script>
